import React from 'react';
import Flex from '@components/Flex/Flex';
import { useField, ErrorMessage } from 'formik';
import clsx from 'clsx';
import styles from './Formik.module.scss';

/**
 * @typedef { Object } IFormikField - Интерфейс для компонента FormikField.
 * @property { React.ReactElement } children - Дочерний компонент, передаваемый внутрь FormikField.
 * @property { string } name - Имя для поля ввода. 
 * @property { string } className - Название класса для дополнительных стилей компонента.
 */
interface IFormikField {
    children: React.ReactElement,
    name: string,
    className?: string,
    errorClassName?: string
}

/**
 * @function FormikField - Компонент оборачивает поле ввода для использования с Formik.
 * @param { IFormikField } - Пропсы для компонента FormikField. 
 * @returns { React.ReactElement } - Поле ввода для Formik.
 */
export const FormikField: React.FC<IFormikField> = (
    {
        children,
        className,
        errorClassName,
        name
    }
): React.ReactElement => {

    const [field, meta, helpers] = useField(name);
    const { setValue } = helpers;

    const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        setValue(event.target.value);
    };

    const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
        field.onBlur(event);
    };

    return (
        <Flex flexDirection="column">
            {React.cloneElement(
                children,
                {
                    ...field,
                    name: { name },
                    className: clsx((meta.touched && !!meta.error && styles.error), className),
                    onChange: handleChange,
                    onBlur: handleBlur
                })
            }
            <div className={clsx(errorClassName, styles.errorString)}>
                <ErrorMessage name={name} />
            </div>
        </Flex>
    )
};
